package com.ac.scum.log.task.face.log.counsumer.stages.gamplay;

import com.ac.common.core.id.SnowflakeIdGenerator;
import com.ac.scum.log.bean.Player;
import com.ac.scum.log.bean.PlayerAlarm;
import com.ac.scum.log.bean.PlayerUnbombScoreNotCounted;
import com.ac.scum.log.bean.ServerFTPLogBombDefusal;
import com.ac.scum.log.task.face.log.counsumer.LogConsumer;
import com.ac.scum.log.task.face.log.counsumer.PlayerAlarmInterface;
import com.ac.scum.log.task.face.log.counsumer.stages.GameplayLogConsumer;
import com.ac.scum.log.task.mapper.log.ServerFTPLogBombDefusalMapper;
import com.ac.scum.log.task.utils.map.GameMapZoneUtil;
import com.ac.scum.log.task.utils.queue.FTPQueueItem;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
@AllArgsConstructor
public class BombDefusalConsumer implements PlayerAlarmInterface {
    private final GameMapZoneUtil gameMapZoneUtil;
    private final SnowflakeIdGenerator snowflakeIdGenerator;
    private final ServerFTPLogBombDefusalMapper serverFTPLogBombDefusalMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    public void bombDefusalConsumer(List<LogConsumer.GameLogLine> lines, FTPQueueItem ftpQueueItem, GameplayLogConsumer gameplayLogConsumer) {
        try {
            Pattern pattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[LogMinigame\\] \\[(.*?)\\] User: (.*?) \\((\\d+), (\\d+)\\). Success: (\\w+). Elapsed time: ([\\d.]+). Failed attempts: (\\d+). Target object: (\\w+). User owner: (.*?)\\. Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)");
            Pattern ownerPattern = Pattern.compile("(\\d+)\\(\\[(\\d+)\\] (.*?)\\)");
            List<ServerFTPLogBombDefusal> bombDefusalList = Lists.newArrayList();
            for (LogConsumer.GameLogLine line : lines) {
                Matcher matcher = pattern.matcher(line.getLineContext());
                if (matcher.find()) {
                    ServerFTPLogBombDefusal bombDefusal = new ServerFTPLogBombDefusal();
                    bombDefusal.setId(snowflakeIdGenerator.nextId());
                    bombDefusal.setFileId(ftpQueueItem.getFileId());
                    bombDefusal.setServerId(ftpQueueItem.getServer().getId());
                    bombDefusal.setLineStart(line.getStartByte());
                    bombDefusal.setLineEnd(line.getEndByte());

                    bombDefusal.setCreateTime(LocalDateTime.now());
                    bombDefusal.setServerTime(gameplayLogConsumer.parseTimestamp(matcher.group(1), ftpQueueItem));
                    bombDefusal.setPlayerSteamId(Long.parseLong(matcher.group(5)));
                    Player player = gameplayLogConsumer.getOrInsertPlayerServer(bombDefusal.getPlayerSteamId(), bombDefusal.getServerId(), matcher.group(3));
                    bombDefusal.setPlayerId(player.getId());
                    bombDefusal.setSuccessFlag(matcher.group(6).trim().equals("Yes"));
                    bombDefusal.setTime(Double.parseDouble(matcher.group(7)));
                    bombDefusal.setFailedAttempts(Integer.parseInt(matcher.group(8)));
                    bombDefusal.setTarget(matcher.group(9));
                    String ownerInfo = matcher.group(10).trim();
                    bombDefusal.setOwnerPlayerId(0L);
                    bombDefusal.setSystemFlag(true);
                    if (!ownerInfo.equals("0()") && !ownerInfo.equals("N/A")) {
                        Matcher ownerMatcher = ownerPattern.matcher(ownerInfo);
                        if (ownerMatcher.find()) {
                            bombDefusal.setOwnerPlayerSteamId(Long.parseLong(ownerMatcher.group(2)));
                            bombDefusal.setSystemFlag(false);
                            Player ownerPlayer = gameplayLogConsumer.getOrInsertPlayerServer(bombDefusal.getOwnerPlayerSteamId(), bombDefusal.getServerId(), ownerMatcher.group(3));
                            bombDefusal.setOwnerPlayerId(ownerPlayer.getId());
                        }
                    }
                    bombDefusal.setLocation(matcher.group(11) + "," + matcher.group(12) + "," + matcher.group(13));
                    bombDefusal.setLocationZone(gameMapZoneUtil.getZone(Double.parseDouble(matcher.group(11)), Double.parseDouble(matcher.group(12))));
                    String target = bombDefusal.getTarget();
                    String s = modifyTarget(target);
                    bombDefusal.setTarget(target.replace(s, gameplayLogConsumer.getSpawnItemCodeCnName(s.toLowerCase())));
                    bombDefusalList.add(bombDefusal);

                    PlayerUnbombScoreNotCounted playerUnbombScoreNotCounted = new PlayerUnbombScoreNotCounted();
                    playerUnbombScoreNotCounted.setServerId(bombDefusal.getServerId());
                    playerUnbombScoreNotCounted.setPlayerId(bombDefusal.getPlayerId());
                    playerUnbombScoreNotCounted.setSteamId(bombDefusal.getPlayerSteamId());
                    int type = bombDefusal.getTarget().toLowerCase().contains("c4") ? 1 : bombDefusal.getTarget().toLowerCase().contains("自爆僵尸") ? 1 : 0;
                    playerUnbombScoreNotCounted.setBombType(type);
                    playerUnbombScoreNotCounted.setFailNum(bombDefusal.getFailedAttempts());
                    playerUnbombScoreNotCounted.setFlag(bombDefusal.getSuccessFlag());
                    playerUnbombScoreNotCounted.setUseTime(bombDefusal.getTime());
                    playerUnbombScoreNotCounted.setCreateTime(bombDefusal.getCreateTime());
                    String key = "unbomb-score:" + playerUnbombScoreNotCounted.getServerId() + "-" + playerUnbombScoreNotCounted.getPlayerId();
                    redisTemplate.opsForList().rightPush(key, playerUnbombScoreNotCounted);

                } else {
                    gameplayLogConsumer.commitDiscardLog(ftpQueueItem, line, "bombDefusal no match");
                }
                bombDefusalList.forEach(serverFTPLogBombDefusalMapper::insert);

                List<PlayerAlarm> alarms = Lists.newArrayList();
                if (getCurrentAlarmConfig(ftpQueueItem).getExplosivesEnabled()) {
                    List<Long> hasAlarmPackagePlayerIds = getHasAlarmPackagePlayerIds(ftpQueueItem);
                    if (!hasAlarmPackagePlayerIds.isEmpty()) {
                        bombDefusalList.stream().filter(item -> hasAlarmPackagePlayerIds.contains(item.getOwnerPlayerId())).forEach(item -> {
                            PlayerAlarm playerAlarm = new PlayerAlarm();
                            playerAlarm.setServerId(item.getServerId());
                            playerAlarm.setPlayerId(item.getOwnerPlayerId());
                            playerAlarm.setDetail("bomb defusal table");
                            playerAlarm.setLogId(item.getId());
                            playerAlarm.setLogTime(item.getServerTime());
                            playerAlarm.setServerName(ftpQueueItem.getServer().getName());
                            playerAlarm.setAlarmDetail("拆除" + (item.getSuccessFlag() ? "成功" : "失败"));
                            playerAlarm.setAlarmItem(item.getLocationZone() + "-" + item.getTarget());
                            alarms.add(playerAlarm);
                        });
                    }
                }
                commitAlarmTask(alarms);
            }
        } catch (Exception e) {
            log.error("拆弹日志解析异常", e);
        }
    }

    public static String modifyTarget(String target) {
        int lastUnderscoreIndex = target.lastIndexOf("_");
        if (lastUnderscoreIndex != -1) {
            return target.substring(0, lastUnderscoreIndex);
        }
        return target;
    }

}
